# -*- coding:utf-8 -*-
"""
配置（定时读取配置）文件
"""

import json
import threading
import time
from threading import Timer
from datetime import datetime, timedelta
# from utilities.log_help import LogHelper,TraceHelper,DebugHelper


class ReadWriteLock:
    def __init__(self):
        self._read_ready = threading.Condition(threading.Lock())
        self._readers = 0

    def acquire_read(self):
        with self._read_ready:
            while self._readers < 0:
                self._read_ready.wait()
            self._readers += 1

    def release_read(self):
        with self._read_ready:
            self._readers -= 1
            if not self._readers:
                self._read_ready.notifyAll()

    def acquire_write(self):
        with self._read_ready:
            while self._readers != 0:
                self._read_ready.wait()
            self._readers = -1

    def release_write(self):
        with self._read_ready:
            self._readers = 0
            self._read_ready.notifyAll()


class Singleton(object):
    _instance_lock = threading.Lock()

    def __init__(self, *args, **kwargs):
        # time.sleep(1)
        pass

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            with Singleton._instance_lock:
                if not hasattr(cls, '_instance'):
                    Singleton._instance = super().__new__(cls)
        return Singleton._instance


class Cache(Singleton):
    def __init__(self):
        if not hasattr(self, '_instance_init'):
            self.lock = ReadWriteLock()
            self.cache = {}
            self.cache_time = {}

    def get(self, query):
        self.lock.acquire_read()
        try:
            if query in self.cache:
                if datetime.now() < self.cache_time[query] + timedelta(minutes=10):
                    return 0, self.cache[query]
                else:
                    return -1, self.cache[query]
            else:
                return 1, None
        finally:
            self.lock.release_read()

    def set(self, query, result):
        self.lock.acquire_write()
        try:
            self.cache[query] = result
            self.cache_time[query] = datetime.now()
        finally:
            self.lock.release_write()

    def delete(self, query):
        self.lock.acquire_write()
        try:
            del self.cache[query]
            del self.cache_time[query]
        finally:
            self.lock.release_write()
# 使用示例


def worker(cache):
    # 查询缓存
    res, data = cache.get("query")
    print(f"Worker get: ({res}, {data})")

    if res == 1 or res == -1:
        # 设定缓存
        cache.set("query", "result")


G_Cache = Cache()
if __name__ == '__main__':

    for i in range(3):
        threading.Thread(target=worker, args=(G_Cache,)).start()

    # 让工作线程有机会运行
    time.sleep(2)
